package pe.gob.mininter.dirandro.vaadin.panel.mantenimiento;

import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import pe.gob.mininter.dirandro.model.Opcion;
import pe.gob.mininter.dirandro.model.TipoEspecie;
import pe.gob.mininter.dirandro.service.TipoEspecieService;
import pe.gob.mininter.dirandro.util.BeanValidar;
import pe.gob.mininter.dirandro.util.Constante;
import pe.gob.mininter.dirandro.util.HarecUtil;
import pe.gob.mininter.dirandro.vaadin.util.DirandroComponent;
import pe.gob.mininter.dirandro.vaadin.util.Injector;

import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Item;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.data.util.HierarchicalContainer;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.event.ShortcutListener;
import com.vaadin.ui.AbstractSelect.Filtering;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.TextField;
import com.vaadin.ui.TreeTable;
import com.vaadin.ui.VerticalLayout;

public class PanelMantenTipoEspecie extends DirandroComponent implements ClickListener{

	/*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */

	@AutoGenerated
	private VerticalLayout mainLayout;
	@AutoGenerated
	private HorizontalLayout PanelSecundario;
	@AutoGenerated
	private HorizontalLayout PanelContenido;
	@AutoGenerated
	private VerticalLayout PanelParametroContenido;
	@AutoGenerated
	private HorizontalLayout PanelBtnContenido;
	@AutoGenerated
	private Button btnEliminar;
	@AutoGenerated
	private Button btnCrear;
	@AutoGenerated
	private ComboBox cmbEspeciePadre;
	@AutoGenerated
	private TextField txtTipoEspecie;
	@AutoGenerated
	private VerticalLayout PanelContieneTabla;
	@AutoGenerated
	private VerticalLayout PanelTabla;
	@AutoGenerated
	private TreeTable treeModeloMarca;
	@AutoGenerated
	private HorizontalLayout PanelFiltroTabla;
	@AutoGenerated
	private TextField txtFiltroEspecie;
	/**
	 * 
	 */
	private static final long serialVersionUID = 7865391520559352906L;
	private TipoEspecie tipoEspecie;
	private List<TipoEspecie> lstTipoEspeciePadre;
	private boolean flagNuevaEstado;
	private TipoEspecieService tipoEspecieService;
	
	/**
	 * The constructor should first build the main layout, set the
	 * composition root and then do any custom initialization.
	 *
	 * The constructor will not be automatically regenerated by the
	 * visual editor.
	 */
	public PanelMantenTipoEspecie(List<Opcion> acciones,String height) {
		super(acciones,height);
		buildMainLayout();
		tipoEspecieService = Injector.obtenerServicio(TipoEspecieService.class);
		setCompositionRoot(mainLayout);
		postConstruct();	
	}

	@Override
	public void postConstruct() {
		
		btnCrear.setIcon(Constante.ICONOS.SAVE);
		btnEliminar.setIcon(Constante.ICONOS.DELETE);
		habilitarEdicion(false);
		
		txtFiltroEspecie.setInputPrompt("Tipo de Especie");
		txtFiltroEspecie.setImmediate(true);
		txtFiltroEspecie.addShortcutListener(new ShortcutListener("", KeyCode.ENTER, null) {
			
			private static final long serialVersionUID = 4068232062569621771L;

			@Override
			public void handleAction(Object sender, Object target) {
				shortCutEnter(sender, target);
			}
		});
	    
		treeModeloMarca.setSelectable(true);
		treeModeloMarca.setImmediate(true);
		treeModeloMarca.setNullSelectionAllowed(true);
		treeModeloMarca.setNullSelectionItemId(null);
		treeModeloMarca.addListener(new ValueChangeListener() {
			
			private static final long serialVersionUID = -6124596484581515359L;
			@Override
			public void valueChange(ValueChangeEvent event) {
				boolean esModoNuevo = treeModeloMarca.getValue() == null;
				limpiar();
				if(esModoNuevo){
					treeModeloMarca.setValue(null);
					habilitarEdicion(!esModoNuevo);
				}else {					
					Item item = treeModeloMarca.getItem(treeModeloMarca.getValue());
					tipoEspecie.setId(Long.valueOf(item.getItemProperty("id").getValue().toString()));
					txtTipoEspecie.setValue(item.getItemProperty("nombre").getValue());
					
					for (TipoEspecie tipo : lstTipoEspeciePadre) {
						if(tipo.getId().equals((Long)item.getItemProperty("padre.id").getValue())){
							cmbEspeciePadre.select(tipo);
							break;
						}
					}
					habilitarEdicion(!esModoNuevo);
				}
			}
		});
		
		lstTipoEspeciePadre = tipoEspecieService.listarTipoEspecie();
		cmbEspeciePadre.setInputPrompt("Padre");
		cmbEspeciePadre.setContainerDataSource( new BeanItemContainer<TipoEspecie>(TipoEspecie.class, lstTipoEspeciePadre));
		cmbEspeciePadre.setItemCaptionPropertyId("nombre");
		cmbEspeciePadre.setFilteringMode(Filtering.FILTERINGMODE_CONTAINS);
		
		btnCrear.addListener((ClickListener)this);
		btnEliminar.addListener((ClickListener)this);
		refrescar();
		
	}

	private void refrescar(){
		habilitarEdicion(false);
		limpiar();
		cargarTipoEspecies(tipoEspecieService.listarTipoEspecieMap());
	}
	
	private void limpiar(){
		flagNuevaEstado=true;
		tipoEspecie = new TipoEspecie();
		cmbEspeciePadre.select(null);
		txtTipoEspecie.setValue("");
	}	

	private void habilitarEdicion(boolean flag){
		flagNuevaEstado = !flag;
		btnEliminar.setVisible(flag);
		if(flag){
			btnCrear.setCaption("Actualizar");
		}
		else{
			btnCrear.setCaption("Crear");
		}
	}
	
	private void cargarTipoEspecies(Map<String,List<TipoEspecie>> map){

		HierarchicalContainer hwContainer = new HierarchicalContainer();

		hwContainer.addContainerProperty("id", Long.class, 0L);
		hwContainer.addContainerProperty("nombre", String.class, "");
		hwContainer.addContainerProperty("padre", TipoEspecie.class, null);
		hwContainer.addContainerProperty("padre.id", Long.class, null);		
		
		if(map.get(Constante.OPCION.KEY_PADRE) != null){
			recorrer(Constante.OPCION.KEY_PADRE, map, null, hwContainer);
		}
		treeModeloMarca.setContainerDataSource(hwContainer);		
		treeModeloMarca.setItemCaptionPropertyId("nombre");
		
		treeModeloMarca.setVisibleColumns(new Object[]{"nombre"});
		
		for (Object id : treeModeloMarca.rootItemIds()) 
			treeModeloMarca.setCollapsed(id, false);
		
		for (Object itemId: treeModeloMarca.getItemIds())
			treeModeloMarca.setCollapsed(itemId, false);
		
		treeModeloMarca.setPageLength(treeModeloMarca.size());
	}

	private void recorrer(String nombre, Map<String, List<TipoEspecie>> map, Long objPadre, HierarchicalContainer hwContainer) {
		Item item = null;
		for (TipoEspecie tipoEspecie : map.get(nombre)) {
			
			item = hwContainer.addItem(tipoEspecie.getId());
			item.getItemProperty("id").setValue(tipoEspecie.getId());
			item.getItemProperty("nombre").setValue(tipoEspecie.getNombre());
			item.getItemProperty("padre").setValue(tipoEspecie.getPadre() == null ? null : tipoEspecie.getPadre());
			item.getItemProperty("padre.id").setValue(tipoEspecie.getPadre() == null ? null: tipoEspecie.getPadre().getId());
			
			if (!nombre.equals(Constante.OPCION.KEY_PADRE)) {
				hwContainer.setParent(tipoEspecie.getId(), objPadre);
			}
			if (map.get(tipoEspecie.getId().toString()) != null) {
				recorrer(tipoEspecie.getId().toString(), map, tipoEspecie.getId(),hwContainer);
			} else {
				hwContainer.setChildrenAllowed(tipoEspecie.getId().toString(), false);
			}
		}
	}

	private void shortCutEnter(Object sender, Object target){
		TipoEspecie delito = null;
		if (StringUtils.isNotBlank(target.toString())) {
			if(txtFiltroEspecie.equals(target)){
				delito = new TipoEspecie();
				if(StringUtils.isNotBlank(txtFiltroEspecie.getValue().toString())){
					delito.setNombre(txtFiltroEspecie.getValue().toString());
				}
				Map<String,List<TipoEspecie>> map = tipoEspecieService.filtrarTipoEspecie(tipoEspecieService.buscarPadreHijos(delito));
				cargarTipoEspecies(map);
			}
		}else {
			refrescar();
		}
	}

	@Override
	public void buttonClick(ClickEvent event) {
		if(event.getButton().equals(btnCrear)){
			
			tipoEspecie.setNombre((String) txtTipoEspecie.getValue());
			tipoEspecie.setPadre((TipoEspecie)cmbEspeciePadre.getValue());
			HarecUtil.validar(getWindow(), tipoEspecie, new BeanValidar[]{new BeanValidar("nombre", new Object[]{"Nombre"}, txtTipoEspecie)});
			
			if(flagNuevaEstado){
				tipoEspecieService.crear(tipoEspecie);
			}else{
				tipoEspecieService.actualizar(tipoEspecie);
			}
		}
		if(event.getButton().equals(btnEliminar)){
			tipoEspecieService.eliminarXId(tipoEspecie.getId());
		}
		refrescar();
	}

	@AutoGenerated
	private VerticalLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new VerticalLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("100%");
		mainLayout.setHeight("100%");
		mainLayout.setMargin(true);
		
		// top-level component properties
		setWidth("100.0%");
		setHeight("100.0%");
		
		// PanelSecundario
		PanelSecundario = buildPanelSecundario();
		mainLayout.addComponent(PanelSecundario);
		mainLayout.setComponentAlignment(PanelSecundario, new Alignment(20));
		
		return mainLayout;
	}

	@AutoGenerated
	private HorizontalLayout buildPanelSecundario() {
		// common part: create layout
		PanelSecundario = new HorizontalLayout();
		PanelSecundario.setStyleName("whiteBackGround");
		PanelSecundario.setImmediate(false);
		PanelSecundario.setWidth("-1px");
		PanelSecundario.setHeight("-1px");
		PanelSecundario.setMargin(true);
		PanelSecundario.setSpacing(true);
		
		// PanelContenido
		PanelContenido = buildPanelContenido();
		PanelSecundario.addComponent(PanelContenido);
		PanelSecundario
				.setComponentAlignment(PanelContenido, new Alignment(20));
		
		return PanelSecundario;
	}

	@AutoGenerated
	private HorizontalLayout buildPanelContenido() {
		// common part: create layout
		PanelContenido = new HorizontalLayout();
		PanelContenido.setImmediate(false);
		PanelContenido.setWidth("690px");
		PanelContenido.setHeight("-1px");
		PanelContenido.setMargin(false);
		PanelContenido.setSpacing(true);
		
		// PanelContieneTabla
		PanelContieneTabla = buildPanelContieneTabla();
		PanelContenido.addComponent(PanelContieneTabla);
		
		// PanelParametroContenido
		PanelParametroContenido = buildPanelParametroContenido();
		PanelContenido.addComponent(PanelParametroContenido);
		
		return PanelContenido;
	}

	@AutoGenerated
	private VerticalLayout buildPanelContieneTabla() {
		// common part: create layout
		PanelContieneTabla = new VerticalLayout();
		PanelContieneTabla.setStyleName("h2");
		PanelContieneTabla.setCaption("Filtro de Busqueda");
		PanelContieneTabla.setImmediate(false);
		PanelContieneTabla.setWidth("420px");
		PanelContieneTabla.setHeight("-1px");
		PanelContieneTabla.setMargin(false);
		
		// PanelFiltroTabla
		PanelFiltroTabla = buildPanelFiltroTabla();
		PanelContieneTabla.addComponent(PanelFiltroTabla);
		
		// PanelTabla
		PanelTabla = buildPanelTabla();
		PanelContieneTabla.addComponent(PanelTabla);
		
		return PanelContieneTabla;
	}

	@AutoGenerated
	private HorizontalLayout buildPanelFiltroTabla() {
		// common part: create layout
		PanelFiltroTabla = new HorizontalLayout();
		PanelFiltroTabla.setImmediate(false);
		PanelFiltroTabla.setWidth("100.0%");
		PanelFiltroTabla.setHeight("-1px");
		PanelFiltroTabla.setMargin(false);
		
		// txtFiltroEspecie
		txtFiltroEspecie = new TextField();
		txtFiltroEspecie.setImmediate(false);
		txtFiltroEspecie.setWidth("100.0%");
		txtFiltroEspecie.setHeight("-1px");
		txtFiltroEspecie.setInputPrompt("Especie");
		PanelFiltroTabla.addComponent(txtFiltroEspecie);
		
		return PanelFiltroTabla;
	}

	@AutoGenerated
	private VerticalLayout buildPanelTabla() {
		// common part: create layout
		PanelTabla = new VerticalLayout();
		PanelTabla.setImmediate(false);
		PanelTabla.setWidth("-1px");
		PanelTabla.setHeight("-1px");
		PanelTabla.setMargin(false);
		
		// treeModeloMarca
		treeModeloMarca = new TreeTable();
		treeModeloMarca.setImmediate(false);
		treeModeloMarca.setWidth("420px");
		treeModeloMarca.setHeight("300px");
		PanelTabla.addComponent(treeModeloMarca);
		
		return PanelTabla;
	}

	@AutoGenerated
	private VerticalLayout buildPanelParametroContenido() {
		// common part: create layout
		PanelParametroContenido = new VerticalLayout();
		PanelParametroContenido.setStyleName("h2");
		PanelParametroContenido
				.setCaption("Administración de Tipo de Especies");
		PanelParametroContenido.setImmediate(false);
		PanelParametroContenido.setWidth("-1px");
		PanelParametroContenido.setHeight("-1px");
		PanelParametroContenido.setMargin(false);
		PanelParametroContenido.setSpacing(true);
		
		// txtTipoEspecie
		txtTipoEspecie = new TextField();
		txtTipoEspecie.setCaption("Tipo de Especie");
		txtTipoEspecie.setImmediate(false);
		txtTipoEspecie.setWidth("250px");
		txtTipoEspecie.setHeight("-1px");
		txtTipoEspecie.setRequired(true);
		txtTipoEspecie.setInputPrompt("Tipo de Especie");
		PanelParametroContenido.addComponent(txtTipoEspecie);
		
		// cmbEspeciePadre
		cmbEspeciePadre = new ComboBox();
		cmbEspeciePadre.setCaption("Nivel Superior");
		cmbEspeciePadre.setImmediate(false);
		cmbEspeciePadre.setWidth("-1px");
		cmbEspeciePadre.setHeight("-1px");
		PanelParametroContenido.addComponent(cmbEspeciePadre);
		
		// PanelBtnContenido
		PanelBtnContenido = buildPanelBtnContenido();
		PanelParametroContenido.addComponent(PanelBtnContenido);
		PanelParametroContenido.setComponentAlignment(PanelBtnContenido,
				new Alignment(9));
		
		return PanelParametroContenido;
	}

	@AutoGenerated
	private HorizontalLayout buildPanelBtnContenido() {
		// common part: create layout
		PanelBtnContenido = new HorizontalLayout();
		PanelBtnContenido.setImmediate(false);
		PanelBtnContenido.setWidth("220px");
		PanelBtnContenido.setHeight("62px");
		PanelBtnContenido.setMargin(true);
		
		// btnCrear
		btnCrear = new Button();
		btnCrear.setCaption("Crear");
		btnCrear.setImmediate(true);
		btnCrear.setWidth("-1px");
		btnCrear.setHeight("-1px");
		PanelBtnContenido.addComponent(btnCrear);
		
		// btnEliminar
		btnEliminar = new Button();
		btnEliminar.setCaption("Eiminar");
		btnEliminar.setImmediate(true);
		btnEliminar.setWidth("-1px");
		btnEliminar.setHeight("-1px");
		PanelBtnContenido.addComponent(btnEliminar);
		
		return PanelBtnContenido;
	}
}